﻿using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;

namespace InfrastructureBase.Base.AuthBase.JwtAuth
{
    public class JwtHelper
    {
        private readonly JwtConfig jwtConfig;
        public JwtHelper(IServiceProvider serviceProvider)
        {
            jwtConfig = serviceProvider.GetService<IOptionsSnapshot<JwtConfig>>()?.Value;
        }

        /// <summary>
        /// 生成token
        /// </summary>
        /// <returns></returns>
        public string GenerateToken(Claim[] claims)
        {
            if (jwtConfig == null)
                throw new ArgumentNullException(nameof(jwtConfig));

            var expires = DateTime.Now.AddMinutes(jwtConfig.AccessTokenExpiresMinutes ?? 120);
            // 读取密钥
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtConfig.IssuerSigningKey));
            // 对密钥指定加密算法加密，生成Credentials
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            // 生成token
            var jwtSecurityToken = new JwtSecurityToken(
                issuer: jwtConfig.Issuer,
                audience: jwtConfig.Audience,
                claims: claims,
                expires: expires,
                signingCredentials: creds);

            return new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
        }

        /// <summary>
        /// 验证token
        /// </summary>
        /// <returns></returns>
        public bool IsValidateToken(string token)
        {
            bool isValidate = false;
            try
            {
                var claimsPrincipal = new JwtSecurityTokenHandler()
                               .ValidateToken(token, new TokenValidationParameters
                               {
                                   SaveSigninToken = true,
                                   RequireExpirationTime = true,
                                   ValidateLifetime = true,
                                   ClockSkew = TimeSpan.FromSeconds(30),
                                   ValidateIssuer = true,
                                   ValidateAudience = true,
                                   ValidateIssuerSigningKey = true,
                                   ValidIssuer = jwtConfig.Issuer,
                                   ValidAudience = jwtConfig.Audience,
                                   IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtConfig.IssuerSigningKey)),
                               }, out SecurityToken securityToken);

                var jwtPayLoad = ((JwtSecurityToken)securityToken).Payload.SerializeToJson();

                if (!string.IsNullOrEmpty(jwtPayLoad))
                    isValidate = true;

            }
            catch (SecurityTokenExpiredException ex)
            {

                throw;
            }

            catch (SecurityTokenException ex)
            {

            }
            return isValidate;
        }

    }
}
